{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "84d50ab8",
   "metadata": {},
   "source": [
    "# 实验二：线性回归模型训练与评估\n",
    "\n",
    "## 实验目的\n",
    "1. 掌握线性回归模型的基本原理与实现方法。\n",
    "2. 掌握模型训练、预测及评估的流程。\n",
    "\n",
    "## 实验内容\n",
    "\n",
    "### 1. 导入必要的模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1955007a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.metrics import mean_squared_error"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "032603d3",
   "metadata": {},
   "source": [
    "### 2. 生成数据\n",
    "- 根据线性函数 $y=-5x+0.1$ 生成模拟数据，并在其中加入少许扰动\n",
    "根据实验要求，使用线性函数 $y = -5x + 0.1$ 生成模拟数据。\n",
    "使用 np.random.rand(100, 1) 生成 100 个 $x$ 值，并计算出真实的 $y_{true}$。\n",
    "然后通过 np.random.randn(100, 1) 生成一些高斯噪声，并将其添加到 $y_{true}$ 中，得到最终用于训练的 $y$ 值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "88b6b30d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据生成完成\n",
      "X shape:(100, 1), y shape: (100, 1)\n"
     ]
    }
   ],
   "source": [
    "# 创建 100 个在 [0,1] 范围内的随机 x 值 ， 形状为（100，1） 的二位数组\n",
    "np.random.seed(42) # 为了结果可以复现\n",
    "X= np.random.rand(100,1)\n",
    "# 真实的线性函数 y = -5*x + 0.1\n",
    "y_true = -5*X+0.1\n",
    "# 加入一些高斯噪声 （扰动）\n",
    "noise = 0.5 * np.random.randn(100,1)\n",
    "y = y_true + noise\n",
    "\n",
    "print(\"数据生成完成\")\n",
    "print(f\"X shape:{X.shape}, y shape: {y.shape}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d3501cc",
   "metadata": {},
   "source": [
    "### 3. 模型构建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2170de2d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url();\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator  sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label  sk-toggleable__label-arrow\"><div><div>LinearRegression</div></div><div><a class=\"sk-estimator-doc-link \" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.linear_model.LinearRegression.html\">?<span>Documentation for LinearRegression</span></a><span class=\"sk-estimator-doc-link \">i<span>Not fitted</span></span></div></label><div class=\"sk-toggleable__content \" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('fit_intercept',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">fit_intercept&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('copy_X',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">copy_X&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('tol',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">tol&nbsp;</td>\n",
       "            <td class=\"value\">1e-06</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_jobs',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_jobs&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('positive',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">positive&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = LinearRegression()\n",
    "model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7b6c775",
   "metadata": {},
   "source": [
    "### 模型训练\n",
    "- 查看参数的名称、维度、数据类型、数值以及是否求导（当requires_grad=True时，参数需要求导，进行反向传播）。\n",
    "- 查看第一个可训练参数\n",
    "- 将第一个参数数组化\n",
    "- 使用训练好的模型进行预测\n",
    "\n",
    "由于 sklearn 的 LinearRegression 使用解析解 (如普通最小二乘法 OLS)，\n",
    "\n",
    "它不需要像梯度下降那样指定 epochs 或 batch_size。\n",
    "\n",
    ".fit()方法会一次性完成训练。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "40d59e28",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  display: none;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  overflow: visible;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".estimator-table summary {\n",
       "    padding: .5rem;\n",
       "    font-family: monospace;\n",
       "    cursor: pointer;\n",
       "}\n",
       "\n",
       ".estimator-table details[open] {\n",
       "    padding-left: 0.1rem;\n",
       "    padding-right: 0.1rem;\n",
       "    padding-bottom: 0.3rem;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table {\n",
       "    margin-left: auto !important;\n",
       "    margin-right: auto !important;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(odd) {\n",
       "    background-color: #fff;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:nth-child(even) {\n",
       "    background-color: #f6f6f6;\n",
       "}\n",
       "\n",
       ".estimator-table .parameters-table tr:hover {\n",
       "    background-color: #e0e0e0;\n",
       "}\n",
       "\n",
       ".estimator-table table td {\n",
       "    border: 1px solid rgba(106, 105, 104, 0.232);\n",
       "}\n",
       "\n",
       ".user-set td {\n",
       "    color:rgb(255, 94, 0);\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td.value pre {\n",
       "    color:rgb(255, 94, 0) !important;\n",
       "    background-color: transparent !important;\n",
       "}\n",
       "\n",
       ".default td {\n",
       "    color: black;\n",
       "    text-align: left;\n",
       "}\n",
       "\n",
       ".user-set td i,\n",
       ".default td i {\n",
       "    color: black;\n",
       "}\n",
       "\n",
       ".copy-paste-icon {\n",
       "    background-image: url();\n",
       "    background-repeat: no-repeat;\n",
       "    background-size: 14px 14px;\n",
       "    background-position: 0;\n",
       "    display: inline-block;\n",
       "    width: 14px;\n",
       "    height: 14px;\n",
       "    cursor: pointer;\n",
       "}\n",
       "</style><body><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LinearRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.7/modules/generated/sklearn.linear_model.LinearRegression.html\">?<span>Documentation for LinearRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\" data-param-prefix=\"\">\n",
       "        <div class=\"estimator-table\">\n",
       "            <details>\n",
       "                <summary>Parameters</summary>\n",
       "                <table class=\"parameters-table\">\n",
       "                  <tbody>\n",
       "                    \n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('fit_intercept',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">fit_intercept&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('copy_X',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">copy_X&nbsp;</td>\n",
       "            <td class=\"value\">True</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('tol',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">tol&nbsp;</td>\n",
       "            <td class=\"value\">1e-06</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('n_jobs',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">n_jobs&nbsp;</td>\n",
       "            <td class=\"value\">None</td>\n",
       "        </tr>\n",
       "    \n",
       "\n",
       "        <tr class=\"default\">\n",
       "            <td><i class=\"copy-paste-icon\"\n",
       "                 onclick=\"copyToClipboard('positive',\n",
       "                          this.parentElement.nextElementSibling)\"\n",
       "            ></i></td>\n",
       "            <td class=\"param\">positive&nbsp;</td>\n",
       "            <td class=\"value\">False</td>\n",
       "        </tr>\n",
       "    \n",
       "                  </tbody>\n",
       "                </table>\n",
       "            </details>\n",
       "        </div>\n",
       "    </div></div></div></div></div><script>function copyToClipboard(text, element) {\n",
       "    // Get the parameter prefix from the closest toggleable content\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text;\n",
       "\n",
       "    const originalStyle = element.style;\n",
       "    const computedStyle = window.getComputedStyle(element);\n",
       "    const originalWidth = computedStyle.width;\n",
       "    const originalHTML = element.innerHTML.replace('Copied!', '');\n",
       "\n",
       "    navigator.clipboard.writeText(fullParamName)\n",
       "        .then(() => {\n",
       "            element.style.width = originalWidth;\n",
       "            element.style.color = 'green';\n",
       "            element.innerHTML = \"Copied!\";\n",
       "\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        })\n",
       "        .catch(err => {\n",
       "            console.error('Failed to copy:', err);\n",
       "            element.style.color = 'red';\n",
       "            element.innerHTML = \"Failed!\";\n",
       "            setTimeout(() => {\n",
       "                element.innerHTML = originalHTML;\n",
       "                element.style = originalStyle;\n",
       "            }, 2000);\n",
       "        });\n",
       "    return false;\n",
       "}\n",
       "\n",
       "document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) {\n",
       "    const toggleableContent = element.closest('.sk-toggleable__content');\n",
       "    const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : '';\n",
       "    const paramName = element.parentElement.nextElementSibling.textContent.trim();\n",
       "    const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName;\n",
       "\n",
       "    element.setAttribute('title', fullParamName);\n",
       "});\n",
       "</script></body>"
      ],
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(X,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "437ac21c",
   "metadata": {},
   "source": [
    "### 5. 模型预测\n",
    "\n",
    "- 查看参数的名称、维度、数据类型、数值以及是否求导（当requires_grad=True时，参数需要求导，进行反向传播）。\n",
    "- 查看第一个可训练参数\n",
    "- 将第一个参数数组化\n",
    "- 使用训练好的模型进行预测\n",
    "\n",
    "查看模型学到的参数\n",
    "\n",
    "`model.coef_` 对应斜率 (w) , 即 y = wx + b 中的 w\n",
    "\n",
    "`model.intercept_` 对应截距 (b), 即 y = wx + b 中的 b\n",
    "\n",
    "这里得到的参数已经是数组， 无需数组化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "61f033cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型参数： 斜率[[-5.22988661]] , 截距[0.20754808]\n"
     ]
    }
   ],
   "source": [
    "learned_coef = model.coef_\n",
    "learned_intercept = model.intercept_\n",
    "\n",
    "print(f\"模型参数： 斜率{learned_coef} , 截距{learned_intercept}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0cb94c98",
   "metadata": {},
   "source": [
    "使用训练好的模型进行预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7e576062",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测完成，预测值 shape: (100, 1)\n"
     ]
    }
   ],
   "source": [
    "y_pred = model.predict(X)\n",
    "\n",
    "print(f\"预测完成，预测值 shape: {y_pred.shape}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fe3901b",
   "metadata": {},
   "source": [
    "### 6. 可视化\n",
    "- 可视化模拟的样本数据、真实的线性函数和训练得到的线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "476d7883",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0QAAAIiCAYAAADowwjdAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlA5JREFUeJzt3QeYU9XWxvE1DL03BRFEkSaCDZAr9gJ2RL3XAgq2C4q9f2IFFXu7duyoYBexIvaCCioISFURBWwIAoL0fM+7D2fIZJJMMpNJTpL/73lyM0lOkjPh3PG8WXuvXRAKhUIGAAAAAHmoUqZ3AAAAAAAyhUAEAAAAIG8RiAAAAADkLQIRAAAAgLxFIAIAAACQtwhEAAAAAPIWgQgAAABA3iIQAUBArV27Nur969atS+j5kydPtr///rvE/StWrLDPP//c1q9fb+nywAMP2K+//pr08xYvXmyTJk0qdp9u//jjj0W3Z86caTNmzCj3Pq5Zs8ZWrVpV4n4t11faZ6V/k2R/v/fff99WrlxpqbBo0aKUvA4A5CMCEQAE1CGHHGKPPPJIsfu++OILq1WrlgsAl156qS1btizm83feeWf78ssvS9yv5+622262fPlyS5czzjjDpk+fbn/99VfMy4YNG0o874033rA999yz2H1nn322Pf7440W3b7zxRrv++uujvu/333/vAlOsS3jQueSSS+zf//53idd48cUXrVGjRiXuX7JkSdHP06ZNsy222CLhz2PChAl20EEH2VVXXWXJeOmll+w///lPift33313e+6550oN2PE+i/CLwiEA5IvKmd4BAEBJf/75p3344YfuJD3cP//8405WFR7Gjx9v3bt3t3feeceaNm1a6msOGTLE+vfvn9D7n3TSSfbEE08kvL977723ffDBB0W3f/nlF7v44ottxIgRVqmS993byy+/bPvvv3/M15g6dap17Ngx5uP//e9/3Un9nDlzXOXLrxJ98sknroqjfW7evLldd911xfZrwYIFMV9T+3zssce6906E3kf/LgsXLrTTTz/dxowZY/vss48l46effnLBq06dOvbWW2/Z4MGDrWHDhgk9V+87ceLEEvfr86hcOf5/0vU5bLfddgm9j0Jz+/btE9oWALIdFSIACCAFCYWc/fbbz5YuXVri8Xbt2rkgdNhhh9n8+fNLHdKlE3lVUaZMmZLwPhx++OHuxLi0i4JBJO3z008/Xazqo4qXglK0SyKqV6/uLgpYOvn3bxcWFrqLfq5WrVqx5+iz8V9f+6rPYeDAgXb00Ue7n1X5+e233xIePqjt9t13X2vWrJl7naOOOiqpoXIKNPo3rVq1qn377be20047uc8lvNoU6ZlnnrHevXu7y0MPPWS///570e0rrrjC/R6qsDVu3DihfVCg1HN06du3rwvJ/u2ff/454d8FAHIFFSIACBjNY7ntttvs/PPPd/N9WrVqZc8++6x16NChaAhcnz593An+7Nmz7aabbir2jb4qAaowyWuvveZOlnfZZRdXXdFcl3nz5hWdGKtKIapQbL755sX2o27duglVCaINJ4tGISCRSpbcfvvtbjiZ9nf16tVWu3ZtN3TuzTfftC233NK23357F0Zk+PDhLqhoWF4q6bPu2rVr0e2CggK7/PLLi26rEvXCCy+4oHnqqaeW+nqzZs2yQw891P2sMNukSRN79NFHXSD617/+Za+//rq1bt26xPMUvrp06eKGsvnD5X744Qd3XLRs2dL9e2oukqph4a699loXmCLpuf48NA25VJjUa4vCIQDkGwIRAATMLbfc4iodgwYNsptvvtlVRHQy3aNHj2Lh4pRTTnEVhh133LHYkCudbD/55JPu5++++87Nt/Hn2Kgy4tt1112Lfj733HPtzjvvTGr4nCoL4XN5SqNAkSgNKVOIe+WVV1xDBgW7+vXr29Zbb10U6CIpNIYP29PnEP6ZRQ4X0/5EhohwGr6noPn222+7YKF5P9oH/7PUv5FCa2TTh2jee+899ztp/zUvyg+G+nccPXq0q8bp30Nzxo488shiz91rr73c/CSFU83DqlmzpnXq1MnOOussO/HEE928IlWHPv74Y7d9z5497YQTTogZEA888MAS92kfACBfMWQOAAJE1ZAbbrjBDaFSJeSaa65xVYnjjz/eDbEaO3as2+6uu+6yzp07u7kvmqujCoKqSaJtFJREJ82qnujE/bTTTnPDovw5KHoPf6hUrDAUa/icbicrmUC01VZbubk5mi+lCobCkf87nXnmma5DW/glPOj5NL/KDzSiOVe6rTlDCg36+corr4y5DxqCpxCiCo1CqX5WIAqnfXnsscdivoY++6uvvtq93x577OGGv6k6o6F8/kUVPFWK9Jnq9zjuuOOKddHTMaF/Ow2P1FDJFi1a2Lhx41xYVlAcNWqUq/7pMe2jqj4KybEqdwyZA4DiqBABQICo6qCAU6VKFVct0MmvQs2nn37qKgB+BUQVAZ2kt2nTxp386kRaJ9+az6LmBapIaNid5tqo0qSf9bplFTl8TreTpX3xh2YlSmFHQU+VHLUKl3vvvdddIkVWe1RJ0T4rCCnIqLOe6GeFEj2mEKCufX7jh1i0nd5TYSKcwlo8xxxzjBvmpwCrf1uFlljUNVBVLYUs7auGQ2pIo5pJ6N/1+eefL9pWw+0uu+wy++qrr1xjBwVHVY90XGj+loYUxqJjJlIyDTQAINcQiAAgYNQN7n//+5/98ccfbl6JgoSqAFpXSNUKefXVV93kfFUPVAFR1UP0Db+Gv/kn/35L5rZt27pLJvhr+ygQJNrlTHSCryqOnqd1dlQ584ODhoSF0zyqaNUN3ae5SBpaFo32RxUVBSIFr2hVLDVC0DaqJmm+ksJNJFV5NM8pkip8Q4cOdQFFIUzVn1g0fE4XtfBWJzp/fpeCmBpD6PfQRQFOc40UhrRPqpzpOHj33Xfd0Lp69eq5+WaRVHGMXK9JXQwV6vzP1qf5SQCQLwhEABAwCj8XXXSRm7eiypBOwvv16+fm0uikXSfKCgm6aJK9KgKqECk46cRb6/KE06R93Rd5st+gQYOinzV8LnI4WDgFgvDqjm4n2ipak/hF1S5VWqKJFkQUPNQ0QGFIoUJzhPzwo0tpFSJVW1RdqVGjhhu2Fj4UTvf5jjjiCDevRx3xFLZ8+n3176BQqmqT5nGFf2aiqpy207wmP6yG01yfcHrveLQPCijbbLNN0X1+MNK/keYZaZib9l+hSBcdJ1orSQ0eNttsM/f7RFa8FLCSWQRW/2b6nTV0EQByHYEIAAJE3/SrjbXmhGjyvgKO5gr5YUXVAX37r6qQ5q7oG38NJSttDZoBAwa4Ns2iuUia4K8mAf7JdmlD4FSR0iVcomsaKWwoDCWzcKnm0GgYl6pdqpCowqP3mzt3rvtsRPNqNLdIQwJFJ/DhtK2qYhp6GD6f5rzzznPzeTR/R+sWqcW5uqvpMwyvjGjNJ31Weh8NV1PY8LuziSp2Clx6LVWiog1FC99WC+WWRsFNVaVI+nfS/CM1StDcIVXIFIpuvfVW97h+VkhUsNQ6SZHUlVDhOpZoTRUi15YCgFxFIAKAAFHVZ+TIke7kXq2YdVsnuBoe5Q+DUrtptXz2O4tFtsuORtUcv6KjRTxFJ/DxqkI+dZJLppucqEKhfddwOQ3/84f0JUrzptQUwW97rbCioWt+GBKtxxO+9o4qIBpmqOAiCisKAgor4dUtVUvUmlwVH/+zEIUd3fbDoQKM5gwpLITP3/E7ASqUqtHBAQcc4MKmwup9991XFNCiUcDQ0LVoevXqFfczUdhR8NG1qkHqMqg1kUTBWdUiVeAU0CJp8VqfttE8JVW+dAzoWNPvqfD43HPPlVjLCQByHYEIAAJGQ9z0bb7md+jEVyf+Grolixcvdl3idFKr9szxJumXlx8QShMeUnw6uVYYUjjQmkgXXnhhUu+tuTYKgP5wO7nggguKhs2FV1TCh8NpyFv4kEE1ZYjVEU9BJpLalYfPT4qsvKmrn6i6pm0VPtQN7+STT3ZVOLXI1jA/f72hSHpMrbej0fyheFTJUjdAVcw0HFD//toPfdZ33323C3kawqewFquBhqpiWjNJlS81e1AVUsP4FO4UyPzW3+paCAB5IwQACIwFCxaEmjdvrok2oe222y40bNiw0M8//+weGzt2bGirrbYKNWzYMHTttdeGKlWqFLrxxhtDGzZsCPXr1y/08ccfF3stvcb7778f+uuvv0IzZswourzwwgvusQkTJhS7f8mSJUXP7d+/v9sm0cvee+9d4nfRvuuxu+66K7TllluW+hpTp04t8RrPP/98qFatWsXu0+exww47hE455ZTQfvvtFzrkkENCy5YtS/gznjNnjnu/uXPnJrS99qFevXpFt6+//vrQb7/9Fho/fnyoZcuWoX333Te0cuVK99jNN98c2nbbbUOrVq0q9hqTJk1y76l/I71vtIv+va+++uoS779+/frQ0KFDQ4WFhaEzzzzT3bd8+fLQwQcfHJo2bVrovvvuC1WpUiX0yiuvhB5++GF3XDz11FMl3l/PrV69euiwww4LLVy40N1/7LHHun9r0e9w7rnnutfSNmPGjAmtXr064c8VALIVgQgAAubOO+90YcWnn7t37+5OqHv16hWaP3++u18nvzp5VRipU6dO6IknnogaiB577LGEQs39999f9FydJB955JEufJR2Oeecc4oFon/++Sd0+umnu9c89dRT3X3fffddsfAVeSktEK1du9YFkPPOOy9Ut27d0FlnnRVas2ZN6Pfffw/tscce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ZuvWede6rfv79cuNpTdatmzpQphCkIbBXXXVVa6Jglpvq/W3qlUauterVy8bM2aMe466yKkqpCF1c+fOdVUofwif5hP5DR/22GOPDP92+SsHDk0EST79UQQAAB6tM3TVVRqypsVSvbnCulZlSPdX1DpE6aThdRqSpzWDtLiqFmzVvJ9Ro0bZI4884oa8adid5iBp3pI60alJwg8//OCaKGhtIwUqrYnkN1147LHHipopfPbZZ5n+FfNWQUj/AjlCPdzVE15tEutGG69VgTTW9I033rBDDjkk6srD+Sba4myqDCkM5cIfxVTj+EFZceygPDh+4Fu1apWrXmyzzTbFhpfFosVPdd6l863wtX1yeVF2zSNat26dVatWrdj9/rpB8f4/pNPtyHWJ9BnqvvD79R75MHRuQ4zjJ9XHbqLZgDlEqBAKPWrBn6t/FAEAQEn673yudpFVUIkWVhL5MiHaIq3RgkA+hKEgIhChwuTyH0UAAADkBr6vBwAAAJC3CEQAAAAA8haBCAAAAEDeIhABAAAAyFsEIgAAACBBqV6xZvXq1Sl/TSSHQAQAAICcctppp9mNN96Y8PZaNFWLqybi0ksvteHDhxe7r2PHjvbmm2+699RaRdGcdNJJds8995S4f9ttt7Vvv/3WUkVr7jz44INurR/t17Rp09xl/Pjx9ueff1qnTp1S9l65gkAEAACArLXHHnsULXDqXxRuLrvsshL3/9///V/U11Aoeeqpp2zkyJGlvt9zzz1nW265ZbH7fv31V2vUqJF9+umnLviUZvbs2dZPq9XH8fjjj5fY/3iXDz74wD1P1aZnn33WzjnnHHf7888/t549e9rvv/9u8+fPd4u/ojgCUR7R6tGzZ5tNnOhd6zYAAEA2+/DDD23t2rXFLqeccopdf/31Je4fNmyYe07z5s2LhYkGDRq4QNG3b98SQSO8qqPAo9c58MAD7aWXXio21K1GjRp28cUXW8OGDV21KJwqM6JQMmvWLJs3b54LRfH079+/aL9XrVpldevWtQULFpT4nfzL3nvv7Z6n1x04cKBb+PXvv/92zzn66KOtcePG7r232mqrlH7+uYCFWfPEpElmTzxhNmOG2apVZtWrm223nf7PZrbzzpneOwAAgLIpLCwsCjmq1IiGiynMXHXVVe62woD/mO+bb76x1q1b23HHHWfnn3++7bbbbtarVy+76aabbDudJJm5YBXukksusYsuusg++ugjO+OMM1zAGTdunBumtuOOO7pK00477WQrV64s9rzTTz/dJk6caE2bNrWXX37ZvecXX3zh9lHCh7H98ccfbn/12O233259+vRx77Ns2bKiypReq0uXLq7aM3XqVPvyyy/dMEG/sqTbulStWtUFN4U1ve7mm29uY8eOLXpfeeyxxxKqauUyAlGehKGhQ80WLdIfC7NatcxWrNB4WbN588z0t4JQBAAAspnm7iiw6KQ/nMJE5JwfDanTELcff/zRDa076qijXLD56aefXGWlur45NrMLL7zQVXxEQUZBZNddd7X777/fhaiaNWvannvuaW+//bZ99tln1q5dOzcfaNKkSTZz5kxr3769qyJp2Nr2229vhx56qN1yyy2uUvXaa6+5StPWW29tr7/+untcKlfedHr+6KOPWr169WyzzTZzwaZHjx7WuXNn95hC1/777++C0Zw5c4oC0b333utC2w477ODet3fv3m5/HnroIRe8VMXS++uiytNJeR6GhECUJTS87bvvNFHOrF49s9atzSpVSux5qgwpDOnLDv8Lgbp1vduqGI0YYbbjjom9HgAAyB9dhnexX/8uXlnx6UQ/vNKQKk1rN7UvB3xZpueqiqKqSOR9kRREJk+ebMcff7wLCPfdd5+tWLHCDT3zw5D44UO22WYbF378YXPnnnuue42vv/7aVWr+85//2A8//OCG3+28887Wpk0b9zwNxatfv76rDunzUgDRfKWDDjqoqLql6/AgFE7BSsP/DjjgADvkkEPcayh0qULVokULV9lSIPINHTrUlixZYnfeead1797d7Zd+J92vz0Kvp/fS8LnDDz+8TJ9zriEQ5fhwN4UoPU+Voci/Wbqt+6dP97Zr27ZCfw0AAJBlFIYWLF9g2UJVkMiQpuBWp06dEttqaNv777/vgoWaECiU/PLLL264WjTaXhWbXXbZxUaPHu2GoZ199tluGJt+1rydY445xoUThaFmzZoVDd8bMmSIjRkzxt1WSFGI8cNQaTSvSc8/+eSTbbpO2jZWw4499lhXwdK+h7vyyitdlUuPKZhpztCZZ55pHTp0cK9z1113FQ0ZvOKKKxLah1xHIMrx4W6qKClE6XnR1KxptnChtx0AAEBktSaWiqwQlZVCQGlD5jRMTtWecNWqVSv6OTIQKZCo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PxNdpwuBKEVatfKu9aVCZIXSX1uoQ4dNawsh9+jvpboGLlrkzRtTSC4s3DSPTPdrHhnD5wAASB2dOD/00EP2zz//lKjaTJ061XaO0rp35cqVduONN9qtt95qTz/9tFWpUsVdXnzxRVdd8m/rMlTfaG6kkHXKKafYv//9b9tjjz2KwonChn+57bbbir1Xly5dbO3ate6i55555plFt3Xp3LmzNdfciigUyBQOjj32WPezwpvC3hdffGGNGjVyYUmXb7/9ttjzVB3T7/H999+7zyBcmzZtXEj59NNP7bfffiv22CKdrJjZZ5995t5PYS5WoIxG4VHhR7+Xwqh+1kX7rYqcfvb16tXL3aeApgqTntOkSRNXITv66KMtnWiqkCJ+o4RGjRJfWwi5RfPD/H/70uaR0UgDAIDUqVatmn311VdWo0aNhLa/4YYb3BA6BZGbbrrJBRlVhm6++WYbP3581OcoiKgKtXTpUhdSFKrkvPPOc5dwffv2LXa7cuXK9uuvv9pzzz3nQsaoUaPcELaHH344ZiVE22+xxRZFt6+++mp77LHH3O+oqtjdd9/t7lelqlatWvbxxx+72wqFquooWPzf//2fq8I0bNjQ3n//fZs0aZK1bdvWdtxxR3cJDygrVqywrl27up+vvPJKF0q0r+FDD/19PfTQQ+21114rdp9su+22Lmi2b9/efU7bb7+9u1/Bslu3bsWCjp6nz0W0j+E/p7M6JJyep9ill5p17qyD0zvx1bXWFopsuY3co/lh+rvCPDIAANJDQ8A0zE2X++67L6HnTJgwwW6//XZX7TnooINclURVHIUdVUZ0Mn7ddddFrX5oPouGmj3xxBNFIejee+8tVvG56667or6vKk2q9GgY25577ukCioaklUbVFV0OPPBAd/t///ufXXPNNS7A6XL99de7wOG77LLLrFWrVnbttde6ipeGqelxzQH617/+5cLfG2+8Ycccc0xRqBH97qrWiIKU3kPbKjTpd1Yly/8dx4wZYz7dVtBTGNLPW221lZ199tnu30SfqS6qoh1//PEudPlULVP4mTVrlu22227uc9e/hSpYBxxwgKUTFaIU22EHs9tvZ22hfKR/a80T0//X/Tll4ZhHBgDIOvpW99dfS9yt7+/rhkIV801+06aaeJPUU3Qi/dRTT7k5QaVRRUXVkblz57qmCqosKUBsvvnm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9DVrA9H8+fPdAlLhfcabNWvmPqw///zTPRZOfd11CW+tJwpV/iJW6eK/X7T3rVlY0z448QPbENpgF79zsd098e4S2xw26jB3fcA2B9gbx7/hfl6/3mz9mjXu58qtW1vBTz9Ffe+XR3t/sA47dI3rLKfFhrt1Mzv+eLOOHbVPsfd7m202/ezeb71VqClTzG66yezPP/Vvu6lN+NSpZjfcYHbppWY77GB5J97xA8TDsYPy4PhBuEaNGtn69evtt99+S+hkVOdnanOcbV9YI/NCKTx+1E5bx260v2OJ/m0L1DpETz75pF1xxRU2b968ovt++OEH23bbbd0qvFqNN9w111xjQ4YMKfE6I0eOdN9sBNkHiz+wO39SfSe253d43qpUKl7+2+P//s8azZwZ93mvvPQSk4AAAECZ6AS1PN+2A+miAB8vyqiCpAViS1uHKFCBSKv4nnXWWcW+mZgxY4ZbzVerBidSIVJoWrRoUUYWZh03bpz16NEjqTGMExdOtN0f3z3uNl+e9qXtsHnxskmlG26wwquvjr9PP/9s1sQbkheL5u788IPXVEEfWatWFZelNDzv4ovNGjSIvSjskiVmt9ziDd9L575lWlmPH4BjB+XB8YOy4thBNhw/ygbKD6UFokANmdtyyy3d0LjwFYYXLFjgymkqhUWqVq2au0TSczP1f85k37t7y+6uAcO3v39rHe/vGHWbLg93cdfX7nutXbHXFd6d6n6gy7vvmh1wQPR98StqY8ea9eyZ8bk8f/9ttny56zbuOttF0khJPa7tpk3Lz3lGmTx2kd04dlAeHD8oK44dBPn4SfS1A/V9+0477WSVK1e28eM3NR/4+OOPbdddd8358anbb769C0ZL/y9s0aAIV75/ZdFir0X2399rKTd3buwXP/BArzPdBRcUC0NDh5p99ZVZw4Zmbdp417qt+/V4qiXaJnzBgvTvGwAAAPJToAKR5v3079/fLrzwQvv222/t/ffft//973925plnWr6oW62uC0a6xOMHIzVqcLbe2gtG/8Rey8juuMMLRgUFrvqiBgyquqiCqKHCutZt3T9ihFfFSWVr7ETahOvx998vfd9o0w0AAIBUCNSQObntttts0KBB1q1bN6tdu7YNHjzYjjnmGMtHfijq+WRPG/fDuKjbFA71Jj1qzSO1+XYlFj9txKmq3XmX99jADsWTiZ6i9t2ffWb2n/+Y/fKL13lO8360plF5hqz5i8KqZ0asNuH77GOmZaf0WOTu+/s2fbo3H6lt27LtBwAAABDYQKQQNGLECHeB5+0T33bXt42/zS4ad1HUbTrc18Fdn7zTyfboEY96dyYQjB4cvjEYDdgUjBSCvvnG7NtvzWrU0PhLr7HBH394YaY8i7f6i8L684MWLvQynBaF1ZpJqkppzpDacUejAKXnaO0kAAAAIOcCEWK7sPuF7jJ3yVxr9b9WUbd5bPJj7iJFw+6SCEZHHRmyL7/01i7abDMvECmkKID4Df2UVbWoa1k7vsVbFFZD8/x5RtGagfjzjPQcAAAAIKfmECEx2zTYxoWdDVfFn0hTogGDglEpXdZfernA/l5RYM1q/uWqNAop6v5Wv75XuVEgUeVIYaY89Loa8ta1q3fth6tE5hlp6J62AwAAAMqLQJTF1HkvmQYM3y3emGJCIZv0dcjea9E/5nN+Wt7AZswssO4rxhUVlxSQ1BJbawVV1JA1f56R5hNpSJ2G6qlCpWvd1v0aWper6xEBAAAgvTitzBF+MNq6/tYxt2lzdxsXjP475r9u2FqDVx63884N2S0dn4j5nEd+7umC0dPzdrfKlb2hdOr6VpFD1vx5Rp07my1e7FWjdK15RuWZvwQAAABEYg5Rjpl7rrce0ZhZY+yIZ46Ius3Dkx52F1l/e8i++66fTVzaz1bMmm/7nLhxMdcIu/wz3mbN9obfnXRIqMKHrMWbZwQAAACkCoEoR/Vq18tVjFatW2U1rq8Rc7vCa72Q4+YkdW5u530Zsg8/CNmkb2Inj8efKDBTUamU+Ujl5c8zAgAAACoKgSjHVa9cvWiOUbEGCxH8x8Yeu8DmzWtmOxeEXAMFvyoU/UkbH6vgYAQAAABUFAYg5ZFEGjAc+PaWNnqnAlt98MnWsqVZ1y4h+1e3UgKPglGclt4AAABAUBGI8jgYDd5jcMxtZlR73MbtXmBfHlbg1h3asL70lt1FwWjNmtTvNAAAAFABCER57Pr9r3fB6Mdzf4y7XbtRBUVzjRJZy8iqVfOC0YQJlo82bPAWmJ040bvWbQAAAAQTc4hgLeu3TGqe0d+X/W21/FDUt6/ZyJHRn9Ctm3d96qlmD3td7XLdpElmTzzhrZmkhWyrV/cWmtXaSrQLBwAACB4qREh6nlHtG2q7cHTle1eaPf20VzF6++3YT3jkkbyYZ6QwNHSo2VdfmTVsaNamjXet27pfjwMAACBYCEQoczC67uPrXDBylaMePbxg9Pff8V84R4ORhsWpMrRokVcRqlvXW8BW17qt+91cLIbPAQAABAqBCAkFozf6vBF3u6JgVKtWYvOMciwYaQFZDZNr3rzkr6Xbun/6dG87AAAABAeBCAk5uM3B3uKtV21IKBiF/FCUJ8Fo6VJvzpDyYDQ1a3qPazsAAAAEB4EISSkoKEhoOF2loZVcMBo1dVRywShLF3mtV89roLBiRfTHtcitHtd2AAAACA4CEcoskWDU56U+m4bTJRKMKlXygtH8+ZZNWrf25gpptyN/Rd3W/R06eNsBAAAgOAhESFkwunzPy+Nul1QwatHCC0Y332zZQDlOrbUbN/bmEi1bZrZunXet27q/Xz9vOwAAAAQHp2dImev2u84Fo5WDVyYXjG69NfbGl16a9DyjTC2MqnWGrrrKrHNns8WLvQYKuu7SxbufdYgAAACCh4VZkXI1qtRIaqHXL//7pXW+MGQ2b57Z1lvHfmE/FMWpLmV6YVS9x447emFIDRQ0Z0jD5KgMAQAABBOBCBUqkWDU5aEu7rpqYVVb7VeN4iWIGMHIXxhVa/6ozbU6vqnJgRZGVdaKVaVRBSmVAUbPbdu27M8HAABA+hCIkNZg1OHeDjZj0Yyo26xZv6YoOLm23RJvqFxYMIpcGNV/yF8YVRUjLYyq6k142Ml0RQkAAACZRSBCWk0/c7q7nrtkrrX6X6uY24UHI4WdSoXxg5EyzoyeoYQWRvWrN2WtKAEAACB3MLMBGbFNg20SatutYFR4bYHtc+hvtvde8bcd+3aBjXqmwKquXVHqwqiRFSVVkgoLN1WUdL8qSulqyAAAAIDMIBAh4xIJRh92bWIf7Vdg9S7bzvbcI/62dz9W2x4cXmC7/PBCzIVRVSnSMLlEKkoAAADIXQyZQ1Y1YFhWbYZ9ckCBFRxgdt5fIbv93R2sYOrUqNsOfOc/7np9QWXbZ/e1rv21vzCqKkWqGGmYXDSqKC1cuKmiBAAAgNxEhShHZGrtnYoKRrOOD9nO09+Iu92d9Qus0tFTvW5zr70Wc7vC0Dr7+JMCu+POgqKGCqoUqWKkOUPRRFaUAAAAkJuoEOWAXOyUpspMnV8PtlPrhNzcnuHNSl/PaO36tTZtwjrbabcasV944/i41utD7jNSA4XwrnSifDV/vhWrKAEAACA3USHKcn6nNJ3YN2xo1qaNd63bul+PZ6PICs6AhSF3iafKtVVs57E17OKxF9vsWfG3Vde6O+8qsMaNvSC5bJnZunXetW7r/n79WFAVAAAg13G6l8VyuVOaKjP6HVSpCV9/VaHovwvih51bP7vF2o0qsIJrSi7eGunl0QVuON3ixV4DBV2rMlTRLbdzaYgjAABANmPIXBZLplOav/ZOtlBlRkP+tB6Q/zuq0YHm9igk9f4j5ELLY7+eY3dPuDv+cLprNjZsiLPIq1p2y+yZG6x1m01zjdI1xLFjR7O99qq49wQAAEB0VIiyWCKd0sLX3sk2qtAo9HTubDErOP87+H8u7Ky5Yk3c11IwSqRi1LZ9JW8R2K+/rpCqTqwhjpMne49PmZL8awIAAKDsqBBlsfB5Nhoml4ud0hR6dtzRC0MKdvpdNJwusoJTpbBKQm27/YrRqKNH2XGdjo/9xkphcuSRZi+9lJLGFZFDHP2Clf7tGjTwfh41yns95i4BAACkB6ddWSzWPJvwTmkdOmR/pzSFAw3569rVuy4tLCSy0OvxLx7vKkauanTBBbE3fPlll1x23qWg3I0rShviKDNnllwMlvlGAAAAFYcKURYrbZ5NvndK80NR4dBC2xCKnSIK6t7uzTPq94NZq1Yxt1PzBRk4IFTUuEKfuxpXqIpV2udc2hBHWb26+BDHXGypDgAAECR5eqqcOxKZZ5Pv1l+13oWjH8/9Me52BSNaJTTP6MHhBe4S2biiNKUtBivVqm0a4pirLdUBAACChApRDkh0nk2+a1m/ZVLzjGaeOdPabdY+5nYKRbL3XqGEGlf4QxxjLQYr7dt728Wbb5RsZQoefab8fwQAAEQiEOUIf54NEpNIMGp/b3sXjNz2G6+j+fCjArNdvVQT76Q73hDH3383O/BAs+OP97bTXKFcbameiaDD0EMAABALgQh5LZFg5B5PIBgpqeg8fPA+i+yPDY2innT7Qxz9k/OFC72Tc//xHXZIvKW6nputLdVTJZGg4w89VLVNQVKfqYYtqlKncMrQUgAA8huBCHlPFYZZx3vD3iaveNMGfHhIuYLRCx80dtdP73izPbDy4hIn3dGGOLZsafbWW8FuqR60IWeJBB19zgw9BAAA8RCIkNdKVhgOtnO3C7kKwy5j4swz2hiIVozYzmr+MCPqNn2/ucT62iXu5/O3DhU76Y4c4rh2bXLzjdRFUI0z0tVSPWhDzhKdYzVwIEMPAQBAfHwnirxVWhe3r3uVvp5RrX4zXDj6T+9d4m53x50FVqkw/rC8cP58I7VO1wn9smVm69Z517qdzpbqQex2V9qaTn7QmTat9KGHejzfhx4CAJDPCEQIlHQtQhpZYVBlobBwU4VB96vCoO0SWej1hZ2+dsGo6hWlvLHO1iPP4APcUj2ZzymdEpljpcclXqvzTAw9BAAAwcKQOQRGOodlJVphCB9K5YeiS8ddajePvznq666tnHgDBm+jUKBbqpflc0qHROdYdewYrKGHAAAgeKgQIRBVnXQPy0q0whBtKNVNPW5y4UgLvsajYOSHo/JUjPz5Rl27etfpnPxfns+pIvlzrBRoIjOlH3Q6dPA+r6AMPQQAAMFEhQgZr+pkYhHSVHRxq1RQKbGFXhOoGFWpWtWOUIVJb1yligVFELvdlbamk8JQeNCJ1epclSFtQ8ttAADyG4EIZZaq9V0yMSwr1V3cFIz0eSTSmS5uMNJZvbz9tlmPHpZpQet2Fy6ZoJPpoYcAACC4CEQok1RWdTKxCGkyFYZE6aR7/Y4hd9K924tNbPGa36Nul9Aco549vWudtc+ZY5lSEZ9TKiUTdCJbnQMAAAiBCGWSyqpOpoZlVcRQKv+k+8/LfnO3f1/xuzW5tUncYHTT22aXjI/xgvoAE2zAUFGCPuSMoAMAAMqDQIQySWVVJ5PDsip6KNXmtTYvdZ7RpT29y5ZLzebfEefFMhiMGHIGAAByFYEIZZLKqk6mh2Wlq8JQWjBaUC+1LbtTjUoMAADIRXy/iwpte5xoVScIi5CmSyILvaaqZTcAAACysEI0Z84c69Spk63yl5pH4FRUU4J8Gpblh6KP5n1kez++d9RtglwxAgAAyAWBO9WcP3++9erVy1avXp3pXUEGqjqZXIQ0U/ZquZetGbzGRu80OjUVI6VUAAAAZF+FaPTo0TZw4EBr1qxZpncFCcq3qk5FUzCqUqVKzHlGCVWMtt7auz73XLM776yAvQQAAMgdgTptffPNN23IkCF2xx3xWm0haPKxqpPpeUZ+xWjaZnFe5K67mGcEAACQTRWiBx980F1/8MEHCW2vYXXhQ+uWLVvmrteuXesu6eS/X7rfF7kh1vGjipFc/8n1NuSjISWe1+lM73qfuWbvPxHnDTaGorVrvNdD7uBvD8qD4wdlxbGDbDh+En39glAoeDOxFYj23XdfK23XrrnmGldRijRy5EirqRn+QA7qPbl3zMcqbTBbP7T013hldOz5SgAAALlg5cqV1qdPH1u6dKnVjbZOTKYD0bBhw9wlfLjcnnvumVQgilYhatGihS1atCjuL11RCXTcuHHWo0cPNwcEKM2UKQrvZrNmmW3YsNYGDhxnn37aw449tortsEPpz686rGrcx+POM9qIilH2428PyoPjB2XFsYNsOH6UDRo3blxqIMrYkLlBgwa5xOZr2rRp0q9RrVo1d4mkDzZT/+fM5Hsje0yaZHbddWaLFnkty/0FbL/6qorNmVMloS59pS30mkgDhipVN4aq4BWKkST+9qA8OH5QVhw7CPLxk+hrZywQ1a9f312AfLNhg9kTT3hhSIvbanpPYaH3WLt2ZlOnmo0Y4XXvS6RBhR+MdnpgJ/vmt2/Kt5bRP/+YVa9eht8KAAAgO9EPDEgztSj3F7ONbACn27p/+nRvu2RMPn2yC0fLL1te9rWMatTwduKFFyzXQujs2WYTJ3rXug0AABC4LnNAPtB6TatWmdWqFf1x9QNZuNDbrixqV60ddzhdQhWj//xn086sWGHZPjxRFTmFUH3uKoCpMte/f9kWDwYAALklkBWiffbZp9SGCkC20nwhnZTHyhkrV3qP+/OKKmo9I79idMkBcV5AO5PFaxkpDA0dqrlZZg0bmrVp413rtu7X4wAAIL8FMhABuax1a69CMX9+yV4Guq37O3TwtkuVeMHolj28YNToklJeJMuCUeRcLTWX0VwtXeu27tdcLYbPAQCQ3whEQJqpUYKGazVu7A3j0nrC69Z5j6kFt+7v1y+xhgplDUZTTp9S4rHFNROcZ1TGYJTueTwVNVcLAADkFuYQARmguStqre3PbVG1wr+/b9+Kn9vSqUmn8s8z8lNGAsNbMzGPp6LnagEAgNxAIAIyREFArbVVoViyxOzXX82uv17ra6V3Pyo6GPnzePw1lxRQNH9K83jmzfOCYUWEovC5WtHWYkvlXC0AAJC9GDIHZJCGxbVta7bLLptuZ0oiDRgSGkr37beBmMeTiblaAAAg+xCIAEQNRg8d/lDZglHHjl4wOvTQjM7jiTVXS9e6XZFztQAAQPbgVABAVKftclrMqpEfjD5pEecF3njD2rYrsLFvF8Sdx6N5PhU1j8efq9W5s9nixV7w0nWXLhU3VA8AAGQX5hABKPM8oz1P9a67LDCbWLKgVOThR7znDRwQSvs8nvC5Wgpeei8Nk6MyBAAAhEAEoNzB6MstNw6lC5mFhsR+/oPDNwUjfx6PqjUVPY/Hn6sFAAAQie9IASTNH0p34LYHFn+gILF5RgpGwx8qYB4PAADIOCpEAMrsrRPectdr1q+xatdVS7pl98ujC8xGJ7aWEQAAQEUgEAEot6qFVWMOp0tmLaPvvlpqS9bXZZ4PAABIG043AKRUaZ3p4mnduZ513bXAPjn0BrvgAm9RVwAAgIpEIAIQuGB0yneD7c67CmznXQoIRQAAoEIxZA5AhfJD0Q9LfrBt/7dt0f1+KDp/vNntb8d+vkKR90Ih27CB9tkAACC1CETISZw4B+9zb9WgVdR5Rnd09y51VpktuzHOixcUuJL22T1DbjFXrV+03XZm/fuzwCoAACg7AhFyjoZYPfGE2YwZxolzQD/3aMFoefXEGjCMfdt7zvHHheyrr8zmzTO76ir+bQEAQNnwnTly7qR86FBzJ8oNG5q1aeNd67buZz5KsD73WceHrOf4ss0zGvVMgX38SYEtWmQ2YoRXnQIAAEgWgQg5QyfEqlDoBFmVibp1zQoLvWvd5sQ5eJ+7htRpmz3eCdl/F4RsnyUjkg5GCkV33Flg381hLSMAAJA8AhFyhuauaLhW8+ZFy9oU0W3dP326tx2C8blrfpGG1DVu7L1G099OtFN+CtlxM0NJB6O27St5b/j++6n4tQAAQJ4gECFnaCK/5q7UqhX98Zo1vce1HYLzuWvuj+YAde5stnixF5x0fd5fIfu6V/LByPbbzwtGjRqV8TcCAAD5hKYKyBnqaqaJ/CtWeMO1Iq1c6T2u7RCsz12haMcdo3eoW79jyC3SeleDTeUnPxR99KjZnj/FeFGlKr9kFWI4HQAAiI4KEXKGPx9l/vyS57+6rfs7dPC2Q/A+d4Wftm3Nunb1rv123f6wut6TQ26u0ZbLexc9Z69TvHC088BSdlLBKHI8HwAAABUi5BL/xFltmP05LRqupQqFTso1T6VfP9YjysbP3R9Wp+YNNae+bNuuMqtWfYON617oHp+8RWItuyuqYsS6VwAAZC8CEXJK+ImzTs4XLvSGa3Xp4p2UB22tGv9EesmSTbezUTo+95LD6ipZ69YhFzzC1zNKdzBi3SsAALIbgQg5J958lCAJP5FWEDrrLLPBg81OOCE7T6TT8bn7w+oiRVvoNR3ByF9/Sa3FVRlTYwnNpWLBWAAAsgeBCDkp1olzUESeSPsNByZPNvvhh+w9kc70517uYPTLL2ZNm5Zp/SX/Jfz1lxR0tf6SQmLQwjgAANiE/0wDAVnIVNq1YwHZVAUjXX698NfkWnZvoclIBWZnnlnqe7DuFQAAuYFABKQZJ9Lp06R2k6JwlFQwuu++UjvTse4VAAC5gUAEpBkn0pkRKxgNPKyUJ8YIRuHrL0XDulcAAGQHAhGQZpxIBysYDe/iBaMalycXjFj3CgCA3EAgAtKME+lgBaM3+77pbq+qkuBwuo3ByF9/SessaQjksmVm69Z517rNulcAAGQHuswBAVjIVI0VZNYsTqTT7aDWB5XoTpdoZzo1Arzq61DWrHsFAABKIhABAVjIVJ3l/Pv79uVEOlPKEox23sULRrO/XWtLV1QO7LpXAAAgOgIREICFTJcsMfv1V7PrrzerVi3Te4ayBKO221fxfnj5ZbO2vSt+JwEAQErwHSYQgIVMd9ll020Eb57RmV29dYkSmmN05JGltuzWGlOzZ5tNnOhds+YUAACZQ4UIAEpxzyH3uItfNfJD0SsjzXrNjvNEPxSFdc+YNGnTUEm1V9ecIzXZ0LwyhkoCAJB+BCIAKONwuiP6ePe1/tNszt2lB6NJX4ds6FBvzpiaaWgtKrVf/+orr8mG5pURigAASC8G6ADICkEbZha+ntF3jRIbTqcGDC+PLnAVIXUWLCz0rnVbIWnEiMz/XgAA5BsqRAACL8jDzPxQVGtYLVu5dmVCDRiGP+RVjAYO2FhtKvAqRtOne002NK8MAACkB4EIQODDUDYMM1sxeIW7Xr56udW9sW5CwejB4ZuCUc2a3jpGS5emZXcBAMBGDJkDEFgaPqbKkMJQtgwzq1OtTrHhdIkMpVMweuTRAttmw/duHSMAAJA+BCIAgaXhYxomp8pQZBfryGFmQZRsMHr8k9bWtl2B2b//nZ4dBAAABCIAwaXhY5ozpGFy0WiYmR4P6jAzvxHEhENCNuv4xIORvfhiqWsZAQCA1GAOEYDA0vAxNVDQnCENk4u0cqX3eBCHmUVrBHHudiHr1s1szJdfWcE1Xdx2R003e/G55NYyqsgAp2qbAqY+09atWSwYAJD7CEQAAksn5JorpAYKug4vmCgfzJ9v1qWLt102NYK44orONqROyAWPXc1b6LVwvdm6azMXjILcyQ8AgIpEIAIQWKpO6IRcIcKfS6RhcqoMKQw1bmzWr1+wqhiRjSD8HOM3gtDv8dRTZrfd5u13qOumhV4T6UxXEcEoWzr5AQBQEQJ0GgEAJelEXCfknTubLV7sDenStSpDQTxRL2sjiGQbMKRqjlE2dvIDACCVqBABCDyFnh13zI75LYk0goi33pAfim4bf5sV2EXefXHCUZWqVe0IM1u7bJlZlSoVGuBYMBYAkIsIRACygsJP5Al5EJsApKoRxIXdL3QXKbCC0oOR/2aPP+6NM6ygABfEzxwAgPIgEAHISkFtAlARjSCKhtIlEIzspJO8i/+GKQxwQf3Mg4jgCADZg0AEIOsEuQlARTaCiAxGd7xpdt4X5WvAkGiAW77c7LrrgvmZBw3BEQCyC99XAcgq2dAEoKIbQfgNGJ4f0N01X2jqjawrUwMGP8ApqOkEXlOR1q3zrnVb959wgtmTTwb7Mw9aWFdQbNjQrE0b71q3db8eDzJ/MeGJE71r/k0B5INAVYjef/99u+SSS2zGjBnWqlUrGzZsmB122GGZ3i0AAZItTQDS0Qji01M+tbVr19qY18dYQZ1/l7lltx/g/KqG5gypqqEAp2qWqkHZ8JlnQ8t1BUcdF0EcPkdlC0C+Ckwg+u6771z4uf76661379725ptv2lFHHWVfffWVderUKdO7ByBHurhluhFERahcUNnWDF5jVapUSWyeUZRgFC/AqVqQLZ95JmVLWI9myhSGRALIX4EJRKNGjbIuXbrYeeed526fccYZ9vLLL9uzzz5LIAKQ8i5uuSqpBgwRwShWgOMzz72wHmnkyOytbAFAeQXmT9uxxx5rt2np9jAFBQW2Qv8FBoCIJgCa7B/ZK8BvAtChQ3Jd3HKRP88oqUVep07N6Gee7fNXwoNjNEEOjrNmJb+YMADkisBUiNpGfC2peUSaU3TWWWfFfM7q1avdxbdMs4C1QOHate6STv77pft9kRs4fpJz4oneN+3ff2/WrNmmLm66b4stvCYA69d7l3w/djSUTmYPmmvt7msXv2K0ww7uasP++9v6N99M62euIVuqUujEXH/Wq1Uza9fOrE+fot0KvJYtzTp2NJs82axBg5Id+37/3Rt2pu2C8n91/7jZsGGtC2pqlhFJlSJVj5YsCc5+I/P47xay4fhJ9PULQqEEFqpIs99//9323HNPa9iwoY0fP95ViqK55pprbMiQISXuHzlypNXUf60BACX0ntzb5t1utpX3HVJcr4wenY5dAgAg5VauXGl9+vSxpUuXWt1oY74zHYjUQU4Xn5ooKAQtXrzY9t13X/vrr79cGNpyyy2TqhC1aNHCFi1aFPeXrqgEOm7cOOvRo4eb2AwkI5+Pn/JUBjSk6ocfvBbR+r98q1b5N8ehPMdO1WFVba8fzT58PIH3WbOmQj5zvd7gwV5VRf/ukVUVHReqqlx/ffb820Y7ptu3Nzv++OBVu/zj59NPe9hXX1XJmX8DVLx8/u8Wsuf4UTZo3LhxqYEoY0PmBg0a5BKbr2nTpq4ytP/++9vy5cvtvffeixuGpFq1au4SSR9spv7Pmcn3RvbLt+NHbX7DO1s1berNv5gwwTvpTqSzlea2oGzHTlEDhq0LzEJmoSFxXr9q1Y1PCqX0M9dcoWnTzDbfPPpwO92vqU3qdBa0zmyxaP0pHbcV2XI91Y49torNmVPFfdbRFhPu29cLdkC+/3cL2XX8JPraGQtE9evXdxffqlWr7JBDDrF//vnHPvnkE2uuv8gAcla2r9mSS/xg9Oy/n7XjXjyuTGsZ5WNntiC0XE8VVa7irUVFy20AuSwwTRXuuusumzZtmn3wwQdWvXp1N+xN9HPt2rUzvXsAcmzNFgWybPoGPx2O7Xisu9jVZgVDCtISjGjpHRzpWEwYAIIoMIHohRdecPOBdtttt2L39+/f3x5/PIEB7gCySiYrAxqq538Trn3QCbeqUv378014sapRMsFIk4rq1En6ffyW3loANLxSGN7SW1WKfG+jni7ZVtkCgFQIzPc+EydONPV3iLwQhoDclKk1WxSGhg71TsAbNjRr08a71m3dr8cREYxC3npGcam8ozRzxx1Jn4AriGqeigKqctW6dd61but+DdmiSgEAqCj8JwZA3iywGjlvSefwWnfFn7ek+zVvKdsWBE1nMOr74qZmOFFdcMGmhV4TpKqc5q+oGcHixd6QLV2rMpRIYw0AAHJiyByA/OJXBtQ9zJ9LFNnZKtWVgUzPW8oFTx/1tFnoaVfBH9yjkt3wbmrmGTF/BQCQKfynBkDGpLsykMi8JT2ebR3NMkELZt/wjlc1qn9pqRsnVDHy56907epdE4YAAOlAhQhARqWzMpBtHc2ypRPeXzeGzG5MX2c6AABSiUAEIG86W2VTR7NMd8IrSxhLujMdwQgAEAAEIgB5IxPzlsrTCU9NHrSPGuKnqpaCnPa9ohsNlDeM+cFo0cpF1rjWZqUHI6WvJJowAACQSgEcfAEAFSfoHc0y3QkvlW3JG9ds7FWBSqsEKYEWFNiHI28o9/4DAJAsKkQA8k4q5y2lep5PJjvhRYYx//39MKb9UhjTZ5f07+iHojiVoL37DjbrO9hmNjJrv4jhdACA9CAQAchLqZi3VBHzfBLphLdwYcV0wktLGNsYjMa3KLDu86Nv0v5P5hkBANKHIXMAkOGhZbE64UVTkZ3w0tmWvPvP3lC6L18bHn/DJBd5DSJV3mbPNps40btm4V8ACBYqRAAQoKFlmeyEl4m25F0O/a9Z6L/ejXjBZ+NjP/01z7aqt5Vli0x3CwQAlI4KEQBU4NCysnbCU8c7vceyZWbr1nnXul2RnfD8MKbQFTlSzQ9jHTpUYFvyBBowbFW/pfuQ1do7X6uIAIDUIhABQMCGlmWqE14mw1iywcitcxTgYJTpboEAgMQxZA4AAji0LJWd8JJ9X4Uuf5iXGjjod1EYUxhK6zCvBDrTuWB0TYFtdrHZHzcHpwFDJrsFAgCSQyACAAvmPJ9UdMLLpjBWnmD0xy1mdkuB3bi72UUfrbXKlTL7n7dMdgsEACSHIXMAkK1DyyqQH8a6dvWuA/G7JDCU7v8+NatcWMWFp32f2NcyJZPdAgEAyQnCf+IAIOtkap4PwoLR8Pgtu98/6YOMzTPKeIMKAEDCGDIHALkytCzf/Pe/3kXlllhj08LmGRVcYxa6OpTWKuK8eZvmEmmYnHZVYSgXqogAkCuS/lPct29fe/31122dxocAQJ4L5NCyfKOkEcDOdFQRASBHK0QNGza0AQMG2KpVq+yoo46y4447zvbbbz8ryPKVxAEAOSCJznSqGN17yL02qOugCtsdqogAEHxJ/0m+++67bf78+fbyyy9b9erV7cQTT7RmzZrZueeea59//nnF7CUAAMlIsGI0aNczrfDqiq0aUUUEgGAr059lVYP22msvF45mzpxpJ598sj3yyCO2++6729Zbb2033HCDqyABABD0YLR+qBeODukb3IVeEUxaWHf2bLOJE71rFtoF8qipwt9//21jxoyx559/3saOHWvNmze3888/34499lhbsGCBDR482D777DO3DQAA2TCU7o2R3vXK6wqs1hXpa8CA7DRp0qYFjPUdsNqoq7OgmmkwPwzI8UB0xBFH2Lhx46xBgwZ2zDHH2AcffGC77rpr0eMdO3Z0genUU09N9b4CAJCaYHT00WYvvRR1k5rris8zGrnHFOvcohNzf1AsDA0darZokddBUE0OteaUFmtWZ0GaZgA5HoiaNGniuszts88+MRsp7LnnnvbFF1+kYv8AAEi9F1/0rjXOqV27mJu5YGQ7uGAkX/cKcaKb5zQsTpUhhSFVhPxTobp1vduqGI0Y4TXTIEADORqIhpeyEJ5svvnm7gIAQKCpy0Ginem0iRWYjWE4XT5Tx0B/banIQ0a3df/06d52OrwABB8LswIAIKGQ+/a/UmGCwUi3CUZ5R+3TNWco1lrAWhZr4UJvOwDZgUAEAMBG+lb/7J4ha9jQbNQziQejFYNXWM0qNdO1m8ggrSWlBgqaM6RhcpFWrvQe13YAsgOBCACAKN/+DxzgVX8eHF56MGq+tJYtqGfWafNONuWMKenaXWSAmmtorpAaKITPIRKNvpw/36xLF287ANmBQAQAQJxv/xMJRvPv8K7/t+tUK/id4XS5TI0S1Fpb3eT8uUQaJqfKkMJQ48Zm/frRUAHIJvzfFQCAiG//dWIbuZ7rgP+GbM89QvZP1dhjoc6Z4FWNdNEiryz0mpvUaVCttTt3Nlu82BtqqWtVhmi5DWQfKkQAACTx7f/Mz//yTnhffdWsV6+Yr0UDhtymY0CttRWGNNRS1UXWqgKyE4EIAIAo3/5rrRmFogULvLVnttrK7JhjvJNg5/DDvTLSunVmVaokHIzuOuguO6fbOen4VVDBFH5orQ1kPwIRAAAxvv0fM8bsmWe86pAu999v9sEHXhWpaFhU5cpJrmV0rp371rnefVSNACDjCEQAAETxzTdelWjRIrMWLbzOc2q2oO5iGlIXda5IMsFo4zwjdx/BCAAyhpGuAABE0BA5PwypyYI6zhUWete6rftHjPC2i0rBKLIrQ+QmG5svVF5PAwYAyCQCEQAAETRR3m+qEFns0W3dP326t11cCQSjtdd6weiQ2ZuC0efzPy//LwEASAhD5gAAiLNAazTqPLdwobddQhIYSvf6SO/657pmW9lum57KcDoAqFBUiAAAOUHD12bPNps40buOOZwtyQVao1Ebbj2u7ZLiV4yuuy7mJi2WbRpOJ0EeTpfKzxwAMoUKEQAg602atKlNtio7Ciua61OsG1wZFmhVAwVdhxd2lGfUcU6LcGq7Mrn8cu/y++9mTZpkZQOGVH/mAJApBCIAQFbTifnQoV6jA83tSagbXAoWaO3XLwWLcG6+eZk70y2+ZLE1qNHAKoqqPbEWHa2IzxwAMoVABADImW5wfqbwu8EpzKgbnNYUSja8RC7QqjlDqoKoMqQwlPIT/iSDUcObG7qfN6u5mf1+8e9pq/7os6yozxwAMoFABADIi25wbduWfYHWWJWSCpFkMPpj5R8pHU5XWvVHoagiP3MASDcCEQAga6W8G1wUCj8ZObFPIhi1Odvsu0bln2eUSMXt2WfN/vmnYj9zAEgnitkAgKyVim5wge+UlsBaRnPu9sLRo6OLd6YLlfK8slTcfv7Z+4xS3oEPADKEChEAIO2T8lOlvN3gsqpTmh9udt3VS29RnDzZu/jD6SoN9T7wc7uda3cedGdKKm76N9xyS++zrZAOfACQZgQiAEDKpStolKcbXNZ2SpswwbseP95s990Tmmd01xd3uUtpw+nCK24aJhdJn2uNGmbHHrvp37fCOvABQJrw5woAkFJ+0FCwaNjQrE0b71q3db8eTyW/G1znzmaLF3tVKV2rShEr1ETOldHJf2Hhprkyul+d0gI3fC5c9+5eSaaUnQxf5LW0hV79ipuCTeRoO7/606GDWa9eyX/mABBUVIgAAFnRBjuV3eAqujtdWmmHk+xM5643hqLRO40uU8UtIx34AKAC8GcLAJAyyQSNVNOJuE7IdWKuE3S9R6ziSSJzZfR41nVKS6ABQ2TFqPfk3lZ1WFUbPXN00hU3vwNf167eNWEIQDaiQgQAyKo22KmYt5TIXJms7pQWCrnPY+ddSq8Y1RpstrKq2ZHPHrnpsatDVH+ytNEIgOQRiAAAKZOpoJFsg4TydqfLlqGL5+wRcr/f8IdiB6MVw7zrU3uZPbqL93MqF3pFFnY0BPJMoL6XGDt2rO20005Wu3Zt6969u3355ZeZ3iUAQBISnZSfyqBRlgYJ/lwZzYnRCeqyZWbr1nnXup3tndIihy4OHBByl3geGZNcAwYEt9EIgOQE5k/9999/b71797ZTTjnFpk+fbv/+97/t4IMPtsUauAwAyAqZCBplnbdUlu502T500Q9GI7t5LbhjiRWMFixbUEF7nLtyoqMhkOMCM2Tu559/tgEDBtg555zjbl9wwQV27bXX2scff2xHHHFEpncPAJAgP2j4w4M0Z0jDgxQ0FIZSHTTKM28pVzullTZ08dVtzrEn6p1j/7t2kbXrtlnCnema39F802MMp0tITnU0BHJUYALRPvvs4y6yYcMGe/zxx+2vv/6yelk7oxUA8lc6g0Z55y35ndJySaJzpLbesZ69Mnq0HXLIIValatWEg5H7mXlGgW80AiDLAlH40LmOHTvaqlWr7OSTT7a999475rarV692F98yjckws7Vr17pLOvnvl+73RW7g+EGuHjvbbLPp5/XrvUuqtWxp1rGj2eTJZg0alDz5//13L6Bpu4B+TBXixBO9E+3vvzdr1mzTekK6b4stzE44Qf8eYcfPmjXu57IGozWDveejuNq1zerU0TlL7MCux7VdNh2fQf/bg2Bbm6bjJ9HXLwiFSlmwIM0UaubNm2cTJkywESNG2KhRo6yZ/pJHcc0119iQIUNK3D9y5Eirqb/8AACgTI7o3bvUbQqu1v8Uv+/FHV+0woLCitsxAEjQypUrrU+fPrZ06VKrG+0biUwHomHDhrmL780337Q999yz2DaaT6Rf4AkNRE+wQtSiRQtbtGhR3F+6ohLouHHjrEePHlalSpW0vjeyH8cPyopjZ5MpU/SFmNmsWd638dWqmbVvb3b88WY77GBZt+/t2pn16VP+fddk/R9+8Bpb6D+NrVptGrqYyPETr2Lk63SG2bQmxe/r07GPPd7r8fLtfI7Qv+9NN5n9+WfJal2jRmaXXhr8YzQSf3uQDcePskHjxo1LDUQZGzI3aNAgl9h8K1assE8++cT22GOPovvat29v9957b8zXqFatmrtE0gebqf9zZvK9kf04flBWHDtetzgNjcu2BglquXzddZvWUGra1JsPNWGCF2RS0fFO84jKfPz435tGdgQIM/V+7/rF7cz+faz388hpI93FvUSezzPSsXnZZSXXIVIIqohGI+nE3x4E+fhJ9LUzFojq16/vLr6bbrrJDZH79ttvi+7TOkRbbbVVhvYQAJBtsq1BQmRLZj9z+C2ZdfKslsxqUJHxYOcHo+OOM3v22aibHD2DBgyx5GpHQyAXBOb/hieeeKItWLDArr76aps7d67df//99uSTT9r555+f6V0DAKBClHUNpYx65hkvHE2bltRaRpLvC736gb1rV++aMAQEQ2D+r6jGCWPHjnWXTp062YMPPmjPP/+89ezZM9O7BgBAxloy6/FAtmTefnsvGJUyFTleMHp8MnOMAGReoNpud+vWzT7//PNM7wYAAGlR3jWUAiOBeUbRhtKd/MrJ7pLvw+kAZFZgKkQAAOQbfwFVLZQaWWjxF1Dt0MHbLiuUsWIk+T6cDkDmBKpCBABAEBodpGviu163f3+zefM2zSXyWzIrDDVu7HUhy7q5JklUjBpcavZXjU3304ABQLoRiAAACGuBHdkaWRUchZaKao2s11Vrbf99tTaN3rdLl+xvyZxIMFpyk3d9QU+zO7qXDEbTzphm22++fcXuJ4C8RiACAGBjGBo6dNN6QGp0oLk9X33lVXBSsR5Q3rZkTiAY3f62d3GbhQ2p63h/x00vQ9UIQAXIlT+1AACkbD0gNTgoLNy0HpDu13pA2q6i5EVLZn+O0VNPxd+MeUYA0igX/9wCAJD76wFls759vWCkyVJxEIwApAND5gAAeS+R9YA0tyeQ6wFlsxo1ytyy293eGIpWDF5hNavUrLj9RE5IZ8MUZBcCEQAg7+XMekDZrBzBqNYwL8l2b9HdPj3l04rbR2StTDRMQfYgFwMA8l7OrQeUIH9O1Ndfm82eXbFzpCpiLaOCiP0d//P4Ch1Op89Hn9PEiQH6vJBwwxQ1SGnY0KxNG+9at3W/Hkd+o0IEAMh7ObseUBw6CVRvg732MrviCu93C9Q35glUjDYM9a67n2L22VbFH0v1ekZUGHKjYYp/OPkNU/TvqYYp6vKYS///RnL4pwcAIGw9oM6dzRYv9uYa6FrrAVVky+1MfmM+ebJ3e9ttA/yNeQIVo/GPehWj8Q+XfCwVFSMqDNmLhilIBBUiAADyZT2giG/MO3Xy7gtvMR7Yb8z9UHTOOWZ33x11k93ml96A4dYet9qF3S9M+G2pMGQ3GqYgEfxfFwCAPFoPKOu/Mf/f/7xw9MMPZWrZfdG4i5KqGqXq82L+UeYbpkRDwxQIFSIAAPJIznxjvs025epMl+g8o1R8Xsw/ynzDFA1vDK/whTdM0bDYXGuYguTk2PdeAAAg774xT6IzXTTxKkbl/byYfxSMhilqjKJAumyZ2bp13rVu52LDFCSPf34AAPJITrcYT1EwmrhgYko+r8j5R5p3FD5fS/dr/hHD5ypWPjVMQdkwZA4AgDxtMT5rltmBB276xjxnWownMZSuyUVmv9cu/tiuD++6aburQ2VuyZ7M/CPNV0PFyYeGKSg7AhEAAHn6jbnWIRL1J9CJob4x18l9znxjHgq5IWk77xI7GP12q3c9eD+zG/Yq+bg/lO7rq0JF84A0Z0jD5Er7vHJmvlaONUwBIhGIAADIQzqJ11Cvt94yu+46swYNcu8bc3/I2jl7hNwQtate3MGaL54addth73mXWA0YdhlTYNbAbNbdoYQrDOHzjzRMLifmawE5iEAEAECe8k/md9nFrEoVyzmRQ9au/fcUd3/7+e/Y+W/0KFNnunajvIrR4ksWW6VKDeK+Px3OgOxAIAIAABVeqcnE3I1YQ9ZmNj/ABg4IWWjNWhv+eNUyBaOGNzd01+0atbOZZ80sdb5WsvOPAKQPgQgAAFSYTK7BU9qQteWrqtiBPUN2991mbduVbS2jWX/OiruekT9fK3z+UbVqZttua3bAAV5YU2AkFAGZQyACAAAVwl+DR+2lVR3Ryb/CiYaQqWpS0S2PkxqyVs5FXt39MYJReIezCRPMxo3zgtFDD5k9+SSLtAKZxvcRAAAg5YKwBk+ZFuVMYi2jyuvjr2cUCnsdvYfC4Isvel39GjVikVYgKAhEAAAg5ZJZgyeQi3ImEIzWXusFox4xfodKQyu5YDT43cGBCIgAomPIHAAASLkgrcFTrkU5ExhK9/bG9ZymbWbW6cySj9/wyQ3uorbdxzUPsUgrEDBUiAAAQIU2NIgm3Wvw+Itydu3qXSfdxMCvGA0bFnOTjn9sGk4XyzPtC2x4s4KoAVEBkkVagfQjEAEAgApraKDGBZEjz/yGBloYNuvW4LnsMu8X+PXXuJuVFowUisKDEYu0AplDIAIAAMFoaJBNmjRJqgFDacFo2op3szMgAjkgW/8MAQCAgCtzQ4Nsk4JgNK3zAXZn/QIrvDb2XKVcpmYSs2ebTZzoXdNcAulEUwUAABDMhgbZJgVrGbnH4iz0mosyuXgvIAQiAADyiL5598NJ7drpbWiQyn0PdLBKIhhtdZ7Zz/XzNxhlevFeQAhEAADkichv4uvUMfvvf82mTPGGtQVZEKoISQeyBILRT3d619fvaXbF/vGD0YILFlizOs0sV0SuzeR/TP7aTPq31tpMqjAGMvgiZxCIAADIA9G+iV+92nvsppu85mlB/SY+CFWEcgUyPxj16GH2zjtRN7n8Y+8Sbzjdlrdv6a4b1Whkiy5ZZPm0eC9rM6EikbcBAMhxkd/E6xv4wkLvWv780/smPogT2ePtu27r/oredz+QKYA1bGjWpo13rdu6X48nZNw4LxxNmFCuBgx//vOnqxr5laNcXryXtZmQDgQiAAByXLxv4qVZs03fxGdzFSFrAplWh1UwWr++XMFIsjkYBW3xXuQvAhEAADkum7+Jz/S+V2gg08SYFLTsDg9G6zass2yRs4v3IusQiAAAyHHZ/E18pvc9bYEsRcGoyrVVXDA6/63zLehyfvFeZA0OMQAAcly8b+Jl4cLgfhOf6SpC2gNZEsGo2trY29z5xZ1ZMZwubxbvRaDRZQ4AgBznfxOvjmz+8C9VNnQyL40aBfeb+Hj7rjBU0VUEP5CpgUJ4a+jwQKaT95QHsgRadq+63rv+3+AD7Nyq0bvXZcN6Rnm1eC8CiUMNAIA8EO2b+CVLvMcuvTTY38RnsoqQ8WFdfsUozhucM+wdVzHa8PjWcV8qyBUjf/Fe9ZvQNWEI6USFCACAPBH5TXzt2mazZ5vtsIMFXiarCH4g89ch0hBDDZNTIFMYSkuY9DvSPfaY2SmnRN2k4Mcfi+YYxVrLyD22MRS9dvxrdmjbQ8u1W/r3+Pvv2P8eSS9mC2QAgQgAgDzifxMva9d6gSgb9z1vh3WdfLJ3UYkqzsSlRILRYaMO27R9ksPppkzxri++2Gz58ugL1ZZrMVsgjcjoAAAA2Tasq25dm/R1yI7snVgDhl233DVlw+kUdG66yfu5QYPoC9WmbDHbgFHFS18iTJzoXQdxMWMkjwoRAABAlglfMHbAf0Ou98KDw2MHmi/+O8Fd/7r8F9viti3K3IDBf98///Rua4FazanyF6pVNUiPa9qTv5it3xcifBstZquKWzYNn6PilbsIRAAA5Bl/XoffVIFvubNPtAVjBw7wQky8YNS0zhbmttqwwQqGVio1GM09d65tXX/rEu/brFmU52xcqPbLL73bLVqUvphtpoZAJsuveCnkaf+1LpVasavipQ6ItAjPblmUywEAQCpO7C64wOzss82uuMK7b/Dg7B3ClK/iLRirYHTqKaXMCapUyRtOd+L3cTfb5q5tXDjSdWnvK35LdIWFCl/MNgPVOFWEVOkqLNxU8dL9qnjxxUL2IhABAJAnIud1bLutd//kydk9ryMfJbJg7IE9QzZ7VinBaNttvWC0ZnDczX7860cXjHZ9o6DU91Xg8SsoaVnMNgPVuFgVL2QnAhEAAHkg1rfc0q4d33JnG3/BWC0M66/hGrlgbIcOGxeM9dcyuvrq2C84bFhRA4bxp4yP+95vdy+wp1pXLXF/+EK1WjMqoX3LAolUxbKp4oWSCEQAAOQBvuXOLWVaMPYaJZ6Q2Zw5cV97t626e+GolFbcvSf3tvs2r2qr1q1y76vjx1+fad99zRo1ytBithmoxmVTxQsl0VQBAIA8kMi33FpwlG+5s0eZF4xVacavGsVLJQUFXgOGUChuS+4RW9Vw15sXXmytvr/ZHnrI2w8FIh1X6kiXkcVsU1yN01DT8K55kVWxbKl4oSQCEQAAeSD8W24Nl4vEt9zZqVwLxurM3h/TFlk2LEMw+r3NLe4ix80M2c8/e6HojDPMttwyg4vZpqgap25yfpXVbx6hMJRtFS+UFMh/urVr11qnTp3sGpV2AQBAeuecIP8WjPUrRvEoGG0cSndXz7vibvpM+wL75IACVx368ENvTlHGF7NNQTVOv8fixV4A1bUqQ7Tczn6BrBDdfPPNNm3aNDv66KMzvSsAAOSEaN9y+5WiWbP4lhsbJVgxOsfMWj3zjG3Tqbd1fL56zE0Vij4xs9PnbLB27eK8Zq5X4xBogQtEc+bMsfvuu8+23377TO8KAAA5PedEneX8+/v25VtuJBeMDjvuOHf9f9uPsT/+dbg90iL2tu2f8VLDq8e/aoe1PcyyvRqH3BK4QDRw4EAbMmSIPfXUU5neFQAAck74t9xLlpj9+qvZ9debVauW6T1Dpqnleonqhx+MDjjA7N13oz7vhm97mX1rdlGzfe2Ow96z4c1iB6PDRx1e9HNpXeyAvAxEjz32mK1Zs8ZOPfXUhALR6tWr3cW3TP0cN85B0iWd/PdL9/siN3D8oKw4dlBW22yjYXNrXSBav17/3cz0HiFdoeeHH7wW2Boy2aqVV/WYMsVs5Ehv+KROrRSQtT5Vnz5mO+xgZm++6Z5f8N57Vvmgg6K+dvuF79uDwwvsQTM7c9Aae6fOKTa7RuzzOb9Bw5rBayrot0W+/7drbYKvXxAKlTaDLj3++OMP10jhnXfesY4dO9o+++zjLvEaK+gxVZMijRw50mqq/QcAAABSrtLatXb4f/5T6navjB5t/6z/x46fenyp247eaXSK9g7wrFy50vr06WNLly61utHaa2Y6EA0bNsxdfN26dbOuXbvajTfe6G4nEoiiVYhatGhhixYtivtLV1QCHTdunPXo0cOqVKmS1vdG9uP4QVlx7KA8OH7ypyqkAs9995n9/bdXFapd22vBvmCBN2xSp0277FJyjR1VjDTMUsMqw5sHhB87NWMtbhVm7RqvClR1WNVSt51xxgzbtsG2lmtKrcLlkbVp+tujbNC4ceNSA1HGhswNGjTIJTbfNttsYxMmTLAHHnjA3f7777/t888/t5deesmm6AiKolq1au4SSR9spv6wZ/K9kf04flBWHDsoD46f3DVpktnjj5uNHm32119mdeqYLV/uNQZQZ8HNNvO2Wb/ebN26kj0UNt/cbOpUrzthtGYC7rhJoAFDlapeEPK/h4+3ntF292/nrrtt2c0+P+1zywX6jK+7zmtkog6PTZt6gXTCBG8IY7627q5SwX97En3tjAWi+vXru4tv7ty5xR4/7rjj7F//+pdddNFFGdg7AACA7D8JHzrU3AKpKtAoAMkff3iVIlWElE8qV/Zuq5lC2KmZoxkICxd6j6WqZbfbVGWrggJrd087m/3n7KibfrHgi6LglM0NGPSrqrOjwpDWAvM/HhUsdFsdH0eM8Jqd0MI7z5sqbL311sVuV69e3QWm5orRAAAAKNNJeIsW3tA4fVmuk3Fdq1o0Z453Qq7BNgpMG0e1FbNypc7JvK5zCUskGG0885+ltnbbbutCkcJRLNkcjPQr+mt/RX4kuq37p0/3tqOld2aQQwEAAHJM+Em4Ao+qQBoS55+Ea9qP2q4ru+hnNeOKHF2kx+bPN+vQwWvBnTS9gC6RZadweuGCAmv74Asu7JQWeBSMdPl7zd+WLVRdW7XK+5yjURVOjydUhUN+BaIPPvggbkMFAAAAlH4SrqFZyiSas+LzA5KCkE7IGzXyhsapHbfu17UClYbZ9etXzqFcfvJ67LHY21x+uZfUCgoSCkZ1bqjjgtGl4y61oFN1TVW28M+/3FU45EcgAgAAQPlPwpUzNBRLtzVUTiHIX55F84s0a+Haa826dDFbvNirLulat1M62f+kk7xg9Ntv8bdLIhjdPP7moqpRUKkIpqGJqrZF9nYudxUOuTWHCAAAAKk9Cf/qK7P27b2KkIKP5hIpJKmJgqpGe+xh1r+/F3qOPdYLQ6ouKVDpNSpkkr9a1yXTgGHjtuO+H2c9n+qZdfOM9BnqM1anPn8Yo6pyqgwpDKWkCodyIRABAADkGP8k/JtvzN54w2uy4GcQXSvsXHmlWa9em07EdZ32Sf1JBKMeoU0Vo3gVIf+xDVdtsIJ4r5tGCpyqtqnRhUKRhieqYqcqnMJQPrbcDhICEQAAQJ5QPigs9OYVtWwZoKpEEsHIEgxGlYZ6v9xz/37O/rP9fyzTFHrUWjstVTgkhUAEAACQo2231SDhkEO8xVjVVlvro2px1pkzA7r2TTLBaNmyhILRMS8cY/aCBWI4XUaqcChVkP4vAAAAgBS33dZJuKoRm23mXet2+No3geS37I5HZS6Fo7feKmrAcEuPW+I+JegNGJAZBCIAAIAckzNr3/jBSG25Yzn4YC8YHXGEXdT9IheMVl2+Ku7LEowQjkAEAACQY3Ju7ZvrrvOC0dSpsbcZM6aoZXe1ytWSWuh19p+zU7/PyBoEIgAAgByTs2vfdOzo/QL+QkqxbAxGkkgwandPOxeMDnrqoFTuLbIEgQgAACBH225rjRvNJVq2zGuwoGvdDvLaN2oIMXu22cSJ3rVul6CFlRKZZxQlGJ2000kxNx/7/ViG0+UhuswBAADkoGxc+2bSpE37qzlO2l9VuvzFY1PRsvuxIx5zlz9W/GGb37p51i30itQjEAEAAOSobFr7RmFo6FCzRYu8LnhqCKE5UF99ZTZvnhfu4oa4ZILR+vW2Wa3Nklro9a9L/7J61bNl0hWSEcD/OwAAACDVa9907epdBzEM+esmKQypIqSO2v4Csrqt+7VuUtThc5ESGUqnF1c4mjs34XlG9W+q78LR1e9fncyvhiwQwP9LAAAAIK1zcgK0blJkgUe3y7Rukh+MevSIvU2rVt4bPPhgsWC065a7xnzK0I+GMs8oxzBkDgAAIEeVaU5OQNdN0hyoMq2b9Pbb3vWrr5r16hV9m9NP9y7qYjd1qn1x2hfu7qm/TbUdHtgh5kszzyg3UCECAADIQf6cHM3BadjQrE0b71q3db8ez6t1kw4/3KsYxUtV06YV60zXqUmnpNYzWr9hfTl2EJlCIAIAAMgxKZ2Tk2vrJulDSLJlt9uPBIJR5Wsru2D0+uzXU7CjSBeGzAEAAOSYZObkqNFCUNZNUjc5f781TE6VIYWhCls3KcmW3e5qYyiqf2N9W7o6erXpsFGHuesalWvYystXWr7YsCE7OhpGIhABAADkmAqdk5OL6yaVIRj99X9/ueux3421g54+KOpT/ln3T97MM5qUJfPVoiEQAQAA5JjwOTkaIVYhc3Jycd2kZILRsmVmderYga0PdGFnQ2iDFQ4tjP20BINRNlZZJpV3DakMIxABAADkGH9Ojk5IdR1+fu/PyVHlJSVzcipo3aSKklDg8IPRrrt6/cqj8ZPmxx+b7bGHVSqolNRCr7POmmVtG7XN+irLhoj5av6x5s9X0++i+WoKukENdgHdLQAAAJR3To7m3uiEVMWMdeu8a92usDk5AafAccEFZmefbXbRRd61bsfsuDdhgheOHn009ovuuaeXAvRCSTRgaHdPOxeO+o/un3VdASt8Dak0y7P/GwAAAOQHf05O585mixd7J6S6VmUo6EOYKkK5AsfJJ3vB6KefYm9zxx0xO9PdeeCdMZ824psRLhjtMqYga7oCJjtfTY8Hab5aJIbMAQAA5KiMz8nJtWFdLVpsatkdb8OIBgzn/utcd/l7zd9W54Y6MZ/2yQEF9omZDVgYSqorYCbnHdXL0vlq4QhEAAAAOayi5+TkZRtyPakMnelqV62d0Dyj4c28x0765S+rGqoXtytgpucdtc7i+Wq+PPt+AAAAAPmmQod1lWGR10TnGT2+RX0XjqZWeSRqlSUI844q5cB8tQDvGgAAAJDaYV3RpGRYVzLBSInBf9rVIVt/Zch2WXVhzKdN3OI0e7t7gbUbVRBzGGCq5x1t2GA2e7bXZE/X8V4n2+erMWQOAAAAOS2tw7r8UNSsmdkvv0TfpkoV7/rHH81atnTVk4ePudWGDr3VFiyfbxP3bFF62+7jQ6kdBljOYXjZPF8tC3YRAAAACOawrpiVFE36UTi6/vrYT956ay+9jBxZVGXp3rG59Rwfsr3eK6Vt96gCVzWqUWtTtSkVwwAnlWMYnj9frWtX7zobwpBQIQIAAEDO8wOHX/lQXlHlQ5UhhaGyDOtKqJIyeLB3+eYbs512iv5Cffu6y86HHWY7vvJqWJUl5KoshdfGbsDwWAuv2nToondtyzX7lWsY4IYcWGS1LAhEAAAAyAupHNblV1IUHjQ8TQ0bNEdJlZR586LMndEbq2K0erWXVKJ57TWrVFhgboRb2Hwkv/nCiS+faE9NeSrqU19vvL+73nblcbbfklFlGgb4Xaq78WWJHMp2AAAAQHypGNZVroYG1aqVuTPdk0c+6cLRlNOnxHza9zWfsYe2LHBrGiU7DHBpDiyyWhYEIgAAAMAqppISVxmDUacmnVww2nBV/BZyu4wpcE0YJkwIldopLm3d+AKIQAQAAABYBispZQxGBQUFRW274+n2ZiXXhOG0i36M2xSh9cZufBpuF7k7fje+Dh2CvchqWRCIAAAAgCRUWCXFD0bxJuj4wWj58qK7NCzOX+j18LaHx3zqY/W2cVWjK14enrOLrJZFjv06AAAAQMWq8ErKrFneC117bextNGFJwejLL4vdPfrYMXbukpB1+vKjmE+9fspAN5Su+e3Nc26R1bKgyxwAAACQBL+Som5y/lwiDZNTZUhhKGWVlCuu8C6ffWbWvXv0bdQdQm6+2ezii4vmN23fcE/bbWHINthae7hZ1ahPXbB8QdFCr34nu2xfZLUscvTXAgAAACpOWispu+3mVYyWLIm9zSWXuIrRZgOPKja/qZJVsQELQ+4ST8EQrwHDstXLsnqR1bKgQgQAAACUQdorKfXrb5pnFONNGnzwsn1oBWYfmQ0cUDwEKRRpPtA7mx9mixq+HvX59W70Jj6NP2W87dZiN8sHOZz1AAAAgIqVkUqK5g4l0JnuweEF7hI5v+mESq+5znRv9X0r5nO7P9rdVYwufvtiy3UEIgAAACBbJRGMJkzwut+dcIIX3A5sfaCbO7T8sk0d6yLd+tmtLhg9O+1Zy1UEIgAAACBXglGrVjE3mfxNgY17p8CeemJ9sfWIaletXdS2O5bjXjyuqGK0IVTKCq9ZhkAEAAAA5Irvv/eC0WWXxdzkjrsr2867FNjUd38v8ZgfjI7veHzMilHh0ELb+/G9ixowZDsCEQAAAJBjNlw3zM47N2Tnb/92zG06HdDEm480fnyJx0YePdIFo18u/MVaNyy5oNJH8z5yDRhqDatlc/6cY9mMQAQAAADkGH89ol879XDd5i7o90fsjXff3QtGd95Z4qGmtZvanLPn2OorVketGq1cu9La3tPWDad7Y84blo0IRAAAAECOURvw8PWIVlRv7ILR6aeti/2k88/3gtEhh5R4qGph1aKq0W09b4v69ENHHuqC0axFsyybEIgAAACAHKM1kdRRbsWK4veHKhW6YHT8cXE60735pheM1Es8igt2u8AFo3dOfCfq4/1H97dsQiACAAAAcowWiN1uO2/dociu3P56ROefF7IN6+MEoy+/9ILRzTdHfXj/Vvu7YDT33LnWuGbjovtbNYjd6S6ICEQAAABAjtE6Q/37mzVu7M0lWrbMbN0671q3dX+/fhsXkvVbdm+/ffQXu/RSLxhdd13UNY+2rr+1/XHxH7Zi8Ao33+jx3o9bNiEQAQAAADlo553NrrrKrHNns8WLvUYLuu7SxbtfjxczbZoXeIYPt6iuvNJLUKecYrZ+fYmHa1ap6TrSab5RPKFQyF2ConKmdwAAAABAxVDo2XFHLwyp0YLmFmk4nasMxfLf/3oXjatT1UhlpXCPPeZd9t3X7LXXzGrWTGqfClRtChAqRAAAAEAOU/hp29brkaDruGEoXPPmXopaudLs4IOthPff99rYtWpl9nvJRV6zJRQRiAAAAADEVqOG2RtveMPkzjij5ONz55o1aeIlrdmzLdsEKhBdeOGFLi2GX+65555M7xYAAACASpXM7rvPm2d0440lH9f97dqZPU5ThTKbPn26DRs2zP7444+iy2mnnZbp3QIAAAAQ2XlOAWjkSCshRpvuoApUIJoxY4btuOOO1rhx46JLda0oBQAAACB4jj/eC0YffODdbtDA7LzzLJsEpsvcihUr7KeffrI2bdpkelcAAAAAJGPvvaOuUZQNAhOIZs6c6fqR33vvvfbKK69Yw4YN3ZyiPn36xHzO6tWr3cW3bGNLwLVr17pLOvnvl+73RW7g+EFZceygPDh+UFYcO8iG4yfR1w9UICosLLQWLVrYmDFj7JNPPrGTTz7Zatasab179476nBtuuMGGDBlS4v63337bPS8Txo0bl5H3RW7g+EFZceygPDh+UFYcOwjy8bNS7cITUBDK0DKxap6gi+/NN9+0nXbayerUqVN03znnnOOCkgJOohUiBapFixZZ3bp1LZ2UQPWP2qNHD6tSpUpa3xvZj+MHZcWxg/Lg+EFZcewgG44fZQP1JFi6dGncbJCxCtGgQYOKDYdr2rRpiQYK7du3t/feey/ma1SrVs1dIumDzdT/OTP53sh+HD8oK44dlAfHD8qKYwflUdHHT6KvnbFAVL9+fXfxDR061N5991378MMPi+6bNGmSbbfddhnaQwAAAAC5LjBttw899FAbP3683XbbbTZv3jx76KGH7Mknn7RLLrkk07sGAAAAIEcFJhB17tzZXnrpJReCNFTu9ttvt1GjRlnXrl0zvWsAAAAAclRguszJ4Ycf7i4AAAAAkFcVIgAAAABINwIRAAAAgLxFIAIAAACQtwI1hwgAAABA5m3YYPbdd2ZLl5rVq2fWurVZpRwtpRCIAAAAABSZNMnsiSfMZswwW7XKrHp1My0N2r+/2c47W84hEAEAAAAoCkNDh5otWmTWvLlZrVpmK1aYffWV2bx5ZlddlXuhKEcLXwAAAACSHSb3xBNeGFJFqG5ds8JC71q3df+IEd52uYRABAAAAMA0Z0jD5FQZKigo/phu6/7p073tcgmBCAAAAICpgYLmDGmYXDQ1a3qPa7tcQiACAAAAYOompwYKmjMUzcqV3uPaLpcQiAAAAACYWmtrrtD8+WahUPHHdFv3d+jgbZdLCEQAAAAATOsMqbV248beXKJly8zWrfOudVv39+uXe+sR5divAwAAAKCsdt7Za63dubPZ4sVeAwVdd+mSmy23hXWIAAAAABRR6NlxRy8MqYGC5gxpmFyuVYZ8BCIAAAAAxSj8tG1reSFHcx4AAAAAlI5ABAAAACBvEYgAAAAA5C0CEQAAAIC8RSACAAAAkLcIRAAAAADyFoEIAAAAQN4iEAEAAADIWwQiAAAAAHmLQAQAAAAgbxGIAAAAAOQtAhEAAACAvEUgAgAAAJC3CEQAAAAA8haBCAAAAEDeIhABAAAAyFsEIgAAAAB5q3KmdwAAAABA5m3YYPbdd2ZLl5rVq2fWurVZpTwonxCIAAAAgDw3aZLZE0+YzZhhtmqVWfXqZtttZ9a/v9nOO1tOIxABAAAAeR6Ghg41W7TIrHlzs1q1zFasMPvqK7N588yuuiq3Q1EeFMEAAAAAxBom98QTXhhSRahuXbPCQu9at3X/iBHedrmKQAQAAADkqe++84bJqTJUUFD8Md3W/dOne9vlKgIRAAAAkKeWLvXmDGmYXDQ1a3qPa7tcRSACAAAA8lS9el4DBc0ZimblSu9xbZerCEQAAABAnmrd2psrNH++WShU/DHd1v0dOnjb5SoCEQAAAJCnKlXyWms3buzNJVq2zGzdOu9at3V/v365vR5RDv9qAAAAAEqz885ea+3Onc0WL/YaKOi6S5fcb7ktrEMEAAAA5LmddzbbcUcvDKmBguYMaZhcLleGfAQiAAAAAKbw07at5Z08yHwAAAAAEB2BCAAAAEDeIhABAAAAyFsEIgAAAAB5i0AEAAAAIG8RiAAAAADkLQIRAAAAgLxFIAIAAACQtwIViJYsWWJ9+vSxOnXqWPPmze3uu+/O9C4BAAAAyGGVLUD69u1rS5cutQkTJtjcuXPt6KOPttatW9vBBx+c6V0DAAAAkIMCE4imTp1qb7/9tn3//ffWsmVL22677ezUU0+1zz77jEAEAAAAILcD0QcffGA777yzC0O+e+65J6P7BAAAACC3BSYQqTK0zTbb2M0332wPPPCA1axZ08477zw77bTTYj5n9erV7uJbtmyZu167dq27pJP/ful+X+QGjh+UFccOyoPjB2XFsYNsOH4Sff2CUCgUsgBQ8HnppZdsr732squvvtq+/fZbGzBggI0cOdJ69+4d9TnXXHONDRkypMT9Dz/8sAtUAAAAAPLTypUrXcb466+/rF69esELRMOGDXMXX7du3eyLL76wX3/91WrXru3uO/fcc23mzJk2duzYhCpECxYssA4dOqRh7wEAAABkg59//tl1sA7ckLlBgwa5Fts+DZObP39+URiS9u3b2zvvvBPzNapVq+YuPj1Xv7DadhcUFFg6abheixYt3PvXrVs3re+N7Mfxg7Li2EF5cPygrDh2kA3Hj+o+y5cvt2bNmsXdLmOBqH79+u7i01C5O++80xYvXmwNGzZ0982YMcNatWqV8GtWqlQpbvpLB/2j8ocBZcXxg7Li2EF5cPygrDh2EPTjJ95QucAtzNqjRw9r06aN9e/f32bNmuXmEz3yyCOukgQAAAAAFSEwgahKlSr21ltvWWFhoWu/fdZZZ9kNN9zAGkQAAAAAcr/ttmy55ZY2evRoy0aay6TueOFzmoBEcfygrDh2UB4cPygrjh3k0vETmLbbAAAAAJC3Q+YAAAAAIN0IRAAAAADyFoEIAAAAQN4iECXhn3/+sVNOOcUt/NqkSRMbNmxYzG2//vpr69Kli1WvXt11zfviiy/Suq/I7uPn+eeft44dO7rFhrt162afffZZWvcV2Xvs+P766y/bYost7PHHH0/LPiI3jp+ffvrJDjnkEKtVq5a1bt3annvuubTuK7L32HnzzTdthx12cP/d2nXXXe3zzz9P674iuNasWWMdOnSwDz74ILDnzQSiJFx88cU2ZcoUmzBhgj399NN2yy232KhRo0ps9/fff7v/oBx00EFuTSVdH3bYYW6lXOSvRI+fjz/+2Pr162eXXXaZTZs2zQ488EB3DP36668Z2W9kz7ET+RyOGSRz/Kxfv979t0pdn7T9lVdeaSeccIJNnTo1I/uN7Dl25s2bZ0cddZT7b9e3335rRx99tB166KH2559/ZmS/ERyrV6+2vn372owZM2JuE4jzZnWZQ+lWrlwZql69euj9998vum/IkCGhPffcs8S2jz76aGjrrbcObdiwwd3WdatWrUKPPPJIWvcZ2Xn8nHLKKaF+/foVu69t27ahhx56KC37iuw9dnwffvihO2a22GKL0GOPPZamPUW2Hz9jxowJ1a9fP7R8+fKi+3r16hV68MEH07a/yM5j57nnngs1atSo2H0NGzYMjR49Oi37imD69ttvQzvttJO7KHKEH0tBO2+mQpSgyZMn29q1a6179+5F9+2+++42ceJEhcpi26pMvMcee1hBQYG7rWs9j2Fz+SuZ4+fss8+2Sy65pMRrrFixIi37iuw9dvxv4wYOHGj33nuvVa1aNc17i2w+fjSc5YADDnBDnnyvvPKKDRgwIK37jOw7djp16mTLli2zV1991d1+7bXXbMmSJVavXr207zeC46OPPrJ9993XPvnkk7jbBeG8mUCUoPnz51vjxo2LnWA0a9bMVq1aVaIkrG21yGw4bbtgwYK07S+y9/jZaaedbPvtty+6/e6779rs2bPdHxXkn2SOHdEY/1122cWd2ALJHD/ff/+9tWjRwn0ho+vOnTsXneAi/yRz7LRv397uu+8+6927txty2atXLzv11FNt7733zsCeIyhOP/10u/32292cxHiCcN5MIEqQ/gBErqbr39akw0S2jdwO+SOZ4yecxtL26dPHjj32WDdZFfknmWNHY7QfeOAB9x8gINnjR+P41YRj6dKl9vrrr1v//v3dvJCvvvoqrfuM7Dt2NM/s3HPPtaFDh7oK0hVXXGGLFy/mvAcJCcJ5M4EoQep6oX+wyKEpUqNGjYS2jdwO+SOZ48c3d+5c9y2/viV56KGH0rKfyN5jR0NYNLRpyJAhrhsUkOzfnsqVK1uDBg3s/vvvd1/AnHPOOW6i8/Dhw9O6z8i+Y+eee+6xvfbayy6//HJ37CgYaQidmjAApQnCeTOBKEEq5alErPG0PpXy9I/YqFGjEtv+8ssvxe7TtpHlQOSPZI4fmTNnju25555uuMK4ceNcy1Pkp0SPHbVL1jjtSy+91OrXr+8uum/QoEGuWw/yUzJ/e5o2bepabVeqVKnYUCgNZ0H+SebY+fnnn0uMYlDrZHWnA0oThPNmAlGCNK9D356NHz++WHtk9dr3J4H5/vWvf7kTE3/Soa4//fRTdz/yUzLHz6JFi6xHjx6uMqRJzgpFyF+JHjv6D4eqit98842bDK2LjiF9U/vwww9naO+RTX97dJ9a/YefAGsYZqtWrdK6z8i+Y2fbbbd17bbDzZw504VsoDSBOG9OWz+7HDBgwIBQ586dQ9OmTQu99957rj3ps88+6x77448/QqtWrXI/L126NNS4cePQ5ZdfHpo3b5673nzzzYu1MkX+SfT4Of3001370lmzZrn7/cuKFSsy/Bsg6MdOpJYtW9J2GwkfP4sXLw41adIkdOqpp4bmzJkTGj58eKhKlSqhqVOnZvg3QNCPnenTp4eqVq0auv3220M//PBD6M477wwVFhaGxo8fn+HfAEFhEW23g3beTCBKgv5hTjzxxFCtWrXcfzRuvvnmYv/Q4Scen3/+ueu7rj8Qu+yyS2jixIkZ2mtk2/GjPwq6HXm5+uqrM7j3yJa/PeEIREj2+NG6Ifvss4/7b9c222wTeuaZZzK018i2Y0eBSeFJ2+64446hV155JUN7jWwIRBaw8+aCjTsFAAAAAHmHOUQAAAAA8haBCAAAAEDeIhABAAAAyFsEIgAAAAB5i0AEAAAAIG8RiAAAAADkLQIRAAAAgLxFIAIAAACQtwhEAICsN2XKFKtatao99NBDxe5ftWqVdejQwS644IKM7RsAINgKQqFQKNM7AQBAeV1xxRV277332owZM6xp06buvvPPP9/eeOMNmzx5stWoUSPTuwgACCACEQAgJ6xevdp22mkn23777e2FF16wDz/80A444AD76KOPbLfddsv07gEAAopABADIGZ9++qnttdde9uyzz9qll15qRx99tN18882Z3i0AQIARiAAAOeXss8+2Bx54wNq0aWNff/21Va9ePdO7BAAIMJoqAAByyqGHHmrr1q1zw+cIQwCA0lAhAgDkjBUrVtgOO+xgW2+9tb333ns2duxY69mzZ6Z3CwAQYFSIAAA545JLLrENGzbYmDFj7Mgjj7SBAwe6kAQAQCwEIgBATnj33Xft/vvvd/OHatWqZXfffbctXrzYteMGACAWhswBALLe8uXLrVOnTrb33nvbE088UXS/AtJZZ51l48ePt27dumV0HwEAwUQgAgBkvQEDBrhhctOnT7eGDRsW3a//xO255562dOlS13GuSpUqGd1PAEDwEIgAAAAA5C3mEAEAAADIWwQiAAAAAHmLQAQAAAAgbxGIAAAAAOQtAhEAAACAvEUgAgAAAJC3CEQAAAAA8haBCAAAAEDeIhABAAAAyFsEIgAAAAB5i0AEAAAAwPLV/wOGYx2hd/RpDAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']  # 用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号\n",
    "\n",
    "# 可视化模拟的样本数据\n",
    "plt.scatter(X, y, color='blue', label='样本数据', alpha=0.6)\n",
    "# 可视化真实的线性函数\n",
    "plt.plot(X, y_true, color='green', label='真实线性函数', linewidth=2)\n",
    "# 可视化训练得到的线性模型\n",
    "plt.plot(X, y_pred, color='red', label='训练得到的线性模型', linewidth=2)\n",
    "plt.title('线性回归模型拟合效果')\n",
    "plt.xlabel('X')\n",
    "plt.ylabel('y')\n",
    "plt.legend()\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f3e798c",
   "metadata": {},
   "source": [
    "从实验图像中可以看出，训练得到的线性模型和真实线性函数十分接近，预测效果良好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "116a4b2e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9223860351761157"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.score(X,y)  # R² 决定系数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2833db41",
   "metadata": {},
   "source": [
    "$R^2$ 值计算结果为 0.92 ， 接近 1， 拟合效果良好"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c5e5e9dd",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python-learn",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
